home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2005 March / Macworld CD March 2005 - Marathon Trilogy.iso / Shareware World / iPod / iPodderX.sit / iPodderX / iPodderX.app / Contents / Resources / iPodderX.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2005-01-07  |  28.3 KB  |  1,085 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.3)
  3.  
  4. import urllib
  5. import urllib2
  6. import urlparse
  7. import sys
  8. import os
  9. import re
  10. import string
  11. import plistlib
  12. import download
  13. from threading import Event
  14. from time import *
  15. import feedparser
  16. import typeFile
  17. VERSION = '2.2.6'
  18. USER_AGENT = 'iPodderX/' + VERSION + ' (http://iPodderX.com)'
  19. LITE = 0
  20.  
  21. class iPXURLOpener(urllib.FancyURLopener):
  22.     
  23.     def __init__(self, *args):
  24.         self.version = USER_AGENT
  25.         urllib.FancyURLopener.__init__(self, *args)
  26.  
  27.  
  28. urllib._urlopener = iPXURLOpener()
  29. urllib._urlopener.addheader('Referer: http://iPodderX.com')
  30. userPath = os.path.expanduser('~')
  31. logFile = userPath + '/Library/Logs/iPodderX.log'
  32. rssPath = userPath + '/Library/Application Support/iPodderX/'
  33. downloadDirectory = '~/Desktop/iPodderX Downloads/'
  34. onlyAudio = 0
  35. moveAudio = 1
  36. deleteAudio = 0
  37. moveImages = 1
  38. deleteImages = 0
  39. torrentFiles = 1
  40. organizeDownloads = 1
  41. feedDetails = []
  42. totalBTFileSize = 0.0
  43. DEBUG = 0
  44. timeBombFile = userPath + '/Library/Application Support/.ipx.frf.plist'
  45. pList = userPath + '/Library/Preferences/com.thunderstonemedia.iPodderX.plist'
  46.  
  47. try:
  48.     Prefs = plistlib.Plist.fromFile(file(pList))
  49. except:
  50.     Prefs = plistlib.Plist()
  51.  
  52. feedFile = rssPath + 'feeds.plist'
  53.  
  54. try:
  55.     FeedListPrefs = plistlib.Plist.fromFile(file(feedFile))
  56. except:
  57.     FeedListPrefs = plistlib.Plist()
  58.  
  59. historyFile = rssPath + 'history.plist'
  60. historyURLs = []
  61. encGUIDs = []
  62. History = plistlib.Plist()
  63.  
  64. def trimLog():
  65.     
  66.     try:
  67.         f = open(logFile, 'r')
  68.         data = os.popen('tail -500 ' + logFile).readlines()
  69.         f.close()
  70.         f = open(logFile, 'w')
  71.         for line in data:
  72.             f.write(line)
  73.         
  74.         f.close()
  75.     except:
  76.         pass
  77.  
  78.  
  79.  
  80. def logIt(msg):
  81.     if DEBUG:
  82.         print msg
  83.         sys.stdout.flush()
  84.     
  85.     if os.path.isfile(logFile):
  86.         f = open(logFile, 'a')
  87.         f.write(msg + '\r\n')
  88.         f.close()
  89.     elif os.path.isdir(userPath + '/Library/Logs'):
  90.         f = open(logFile, 'w')
  91.         f.write(msg + '\r\n')
  92.         f.close()
  93.     else:
  94.         os.mkdir(userPath + '/Library/Logs')
  95.         f = open(logFile, 'w')
  96.         f.write(msg + '\r\n')
  97.         f.close()
  98.  
  99.  
  100. def latin1_to_ascii(unicrap):
  101.     '''This takes a UNICODE string and replaces Latin-1 characters with
  102.         something equivalent in 7-bit ASCII. It returns a plain ASCII string. 
  103.         This function makes a best effort to convert Latin-1 characters into 
  104.         ASCII equivalents. It does not just strip out the Latin-1 characters.
  105.         All characters in the standard 7-bit ASCII range are preserved. 
  106.         In the 8th bit range all the Latin-1 accented letters are converted 
  107.         to unaccented equivalents. Most symbol characters are converted to 
  108.         something meaningful. Anything not converted is deleted.
  109.     '''
  110.     xlate = {
  111.         192: 'A',
  112.         193: 'A',
  113.         194: 'A',
  114.         195: 'A',
  115.         196: 'A',
  116.         197: 'A',
  117.         198: 'Ae',
  118.         199: 'C',
  119.         200: 'E',
  120.         201: 'E',
  121.         202: 'E',
  122.         203: 'E',
  123.         204: 'I',
  124.         205: 'I',
  125.         206: 'I',
  126.         207: 'I',
  127.         208: 'Th',
  128.         209: 'N',
  129.         210: 'O',
  130.         211: 'O',
  131.         212: 'O',
  132.         213: 'O',
  133.         214: 'O',
  134.         216: 'O',
  135.         217: 'U',
  136.         218: 'U',
  137.         219: 'U',
  138.         220: 'U',
  139.         221: 'Y',
  140.         222: 'th',
  141.         223: 'ss',
  142.         224: 'a',
  143.         225: 'a',
  144.         226: 'a',
  145.         227: 'a',
  146.         228: 'a',
  147.         229: 'a',
  148.         230: 'ae',
  149.         231: 'c',
  150.         232: 'e',
  151.         233: 'e',
  152.         234: 'e',
  153.         235: 'e',
  154.         236: 'i',
  155.         237: 'i',
  156.         238: 'i',
  157.         239: 'i',
  158.         240: 'th',
  159.         241: 'n',
  160.         242: 'o',
  161.         243: 'o',
  162.         244: 'o',
  163.         245: 'o',
  164.         246: 'o',
  165.         248: 'o',
  166.         249: 'u',
  167.         250: 'u',
  168.         251: 'u',
  169.         252: 'u',
  170.         253: 'y',
  171.         254: 'th',
  172.         255: 'y',
  173.         161: '!',
  174.         162: '{cent}',
  175.         163: '{pound}',
  176.         164: '{currency}',
  177.         165: '{yen}',
  178.         166: '|',
  179.         167: '{section}',
  180.         168: '{umlaut}',
  181.         169: '{C}',
  182.         170: '{^a}',
  183.         171: '<<',
  184.         172: '{not}',
  185.         173: '-',
  186.         174: '{R}',
  187.         175: '_',
  188.         176: '{degrees}',
  189.         177: '{+/-}',
  190.         178: '{^2}',
  191.         179: '{^3}',
  192.         180: "'",
  193.         181: '{micro}',
  194.         182: '{paragraph}',
  195.         183: '*',
  196.         184: '{cedilla}',
  197.         185: '{^1}',
  198.         186: '{^o}',
  199.         187: '>>',
  200.         188: '{1/4}',
  201.         189: '{1/2}',
  202.         190: '{3/4}',
  203.         191: '?',
  204.         215: '*',
  205.         247: '/' }
  206.     r = ''
  207.     for i in unicrap:
  208.         if xlate.has_key(ord(i)):
  209.             r += xlate[ord(i)]
  210.             continue
  211.         if ord(i) >= 128:
  212.             continue
  213.         r += str(i)
  214.     
  215.     return r
  216.  
  217.  
  218. def updatePlaylist(saveLocation, saveName, playList, customGenre):
  219.     print 'Updating iTunes...'
  220.     sys.stdout.flush()
  221.     location = ''
  222.     trackID = 0
  223.     fullPath = saveLocation + '/' + saveName
  224.     song = os.path.abspath(fullPath)
  225.     f = open('/tmp/iPodder-iTunes.applescript', 'w')
  226.     f.write('set theTrackID to 0' + '\r\n')
  227.     f.write('tell application "System Events"' + '\r\n')
  228.     f.write('if exists process "iTunes" then' + '\r\n')
  229.     f.write('tell application "iTunes"' + '\r\n')
  230.     f.write('if (not (exists user playlist "' + playList + '")) then make new playlist with properties {name:"' + playList + '"}' + '\r\n')
  231.     f.write('try' + '\r\n')
  232.     f.write('set theTrack to add POSIX file "' + song + '" to playlist "Library" of source "Library"' + '\r\n')
  233.     f.write('set theTrackID to the database ID of theTrack' + '\r\n')
  234.     f.write('try' + '\r\n')
  235.     f.write('duplicate theTrack to the playlist "' + playList + '"' + '\r\n')
  236.     f.write('end try' + '\r\n')
  237.     if len(customGenre) > 0:
  238.         f.write('set theLibraryID to the index of the container of (the container of theTrack)' + '\r\n')
  239.         f.write('set genre of (some track of library playlist theLibraryID whose database ID is theTrackID) to "' + customGenre + '"' + '\r\n')
  240.     
  241.     f.write('on error theMessage' + '\r\n')
  242.     f.write('log "Error:" & theMessage' + '\r\n')
  243.     f.write('end try' + '\r\n')
  244.     f.write('end tell' + '\r\n')
  245.     f.write('else' + '\r\n')
  246.     f.write('tell application "iTunes"' + '\r\n')
  247.     f.write('set visible of front window to false' + '\r\n')
  248.     f.write('if (not (exists user playlist "' + playList + '")) then make new playlist with properties {name:"' + playList + '"}' + '\r\n')
  249.     f.write('try' + '\r\n')
  250.     f.write('set theTrack to add POSIX file "' + song + '" to playlist "Library" of source "Library"' + '\r\n')
  251.     f.write('set theTrackID to the database ID of theTrack' + '\r\n')
  252.     f.write('try' + '\r\n')
  253.     f.write('duplicate theTrack to the playlist "' + playList + '"' + '\r\n')
  254.     f.write('end try' + '\r\n')
  255.     if len(customGenre) > 0:
  256.         f.write('set theLibraryID to the index of the container of (the container of theTrack)' + '\r\n')
  257.         f.write('set genre of (some track of library playlist theLibraryID whose database ID is theTrackID) to "' + customGenre + '"' + '\r\n')
  258.     
  259.     f.write('on error theMessage' + '\r\n')
  260.     f.write('log "Error:" & theMessage' + '\r\n')
  261.     f.write('end try' + '\r\n')
  262.     f.write('end tell' + '\r\n')
  263.     f.write('end if' + '\r\n')
  264.     f.write('end tell' + '\r\n')
  265.     f.write('return theTrackID')
  266.     f.close()
  267.     ret_pipe = os.popen('/usr/bin/osascript /tmp/iPodder-iTunes.applescript')
  268.     
  269.     try:
  270.         trackID = int(ret_pipe.readline())
  271.     except:
  272.         pass
  273.  
  274.     logIt('TrackID for iTunes is: ' + str(trackID))
  275.     if trackID > 0:
  276.         location = 'iTunes'
  277.         if deleteAudio > 0:
  278.             print 'Deleting: ' + fullPath + '...'
  279.             sys.stdout.flush()
  280.             
  281.             try:
  282.                 os.unlink(fullPath)
  283.  
  284.         
  285.     else:
  286.         print 'iTunes failed to update. Track left in iPodderX Library'
  287.         logIt('iTunes failed to update. Track left in iPodderX Library')
  288.         logIt('iTunes TrackID error:')
  289.         for line in ret_pipe.readlines():
  290.             logIt(line)
  291.         
  292.         sys.stdout.flush()
  293.     if not DEBUG:
  294.         os.unlink('/tmp/iPodder-iTunes.applescript')
  295.     
  296.     return (trackID, location)
  297.  
  298.  
  299. def updateiPhoto(saveLocation, saveName, photoAlbum):
  300.     print 'Updating iPhoto...'
  301.     sys.stdout.flush()
  302.     location = ''
  303.     iPhotoID = '0'
  304.     fullPath = saveLocation + '/' + saveName
  305.     f = open('/tmp/iPodder-iPhoto.applescript', 'w')
  306.     f.write('set thePhotoID to "A"' + '\r\n')
  307.     f.write('tell application "iPhoto"' + '\r\n')
  308.     f.write('if not (exists album "' + photoAlbum + '") then' + '\r\n')
  309.     f.write('new album name "' + photoAlbum + '"' + '\r\n')
  310.     f.write('end if' + '\r\n')
  311.     f.write('set thePhoto to "' + fullPath + '"' + '\r\n')
  312.     f.write('import from thePhoto to album "' + photoAlbum + '"' + '\r\n')
  313.     f.write('end tell' + '\r\n')
  314.     f.write('return thePhotoID' + '\r\n')
  315.     f.close()
  316.     ret_pipe = os.popen('/usr/bin/osascript /tmp/iPodder-iPhoto.applescript')
  317.     iPhotoID = ret_pipe.readline()
  318.     if iPhotoID == 'A':
  319.         location = 'iPhoto'
  320.         if deleteImages > 0:
  321.             print 'Deleting: ' + fullPath + '...'
  322.             sys.stdout.flush()
  323.             
  324.             try:
  325.                 os.unlink(fullPath)
  326.  
  327.         
  328.     else:
  329.         print 'iPhoto failed to update. Image left in iPodderX Library'
  330.         sys.stdout.flush()
  331.     os.unlink('/tmp/iPodder-iPhoto.applescript')
  332.     return (iPhotoID, location)
  333.  
  334.  
  335. def initialize():
  336.     print 'Checking ' + downloadDirectory + '...'
  337.     sys.stdout.flush()
  338.     checkDir(downloadDirectory)
  339.     print 'Checking ' + rssPath + '...'
  340.     sys.stdout.flush()
  341.     checkDir(rssPath)
  342.  
  343.  
  344. def downloadDir():
  345.     defaultDir = '~/Desktop/iPodderX'
  346.     
  347.     try:
  348.         d = Prefs['downloadDirectory']
  349.     except:
  350.         d = defaultDir
  351.  
  352.     if d == '':
  353.         d = defaultDir
  354.     
  355.     d = d.replace('~', userPath)
  356.     if d[len(d) - 1:len(d)] != '/':
  357.         d += '/'
  358.     
  359.     return d
  360.  
  361.  
  362. def checkReg():
  363.     if LITE:
  364.         return 1
  365.     
  366.     if os.path.isfile(timeBombFile):
  367.         return 1
  368.     else:
  369.         
  370.         try:
  371.             regCode = Prefs['iPodderXSerialNumber']
  372.             if len(regCode) > 5:
  373.                 return 1
  374.             else:
  375.                 return 0
  376.         except:
  377.             return 0
  378.  
  379.  
  380.  
  381. def getHistory():
  382.     print 'Loading History...'
  383.     sys.stdout.flush()
  384.     if os.path.isfile(historyFile):
  385.         
  386.         try:
  387.             tempHist = plistlib.Plist.fromFile(file(historyFile))
  388.         tempHist = plistlib.Plist()
  389.         tempHist['downloadHistory'] = list('')
  390.         tempHist.write(historyFile)
  391.  
  392.     else:
  393.         tempHist = plistlib.Plist()
  394.         tempHist['downloadHistory'] = list('')
  395.         tempHist.write(historyFile)
  396.     
  397.     try:
  398.         items = []
  399.         guids = []
  400.         for historyItem in tempHist['downloadHistory']:
  401.             
  402.             try:
  403.                 items.append(historyItem['enclosureURL'])
  404.                 guids.append(historyItem['encGUID'])
  405.             continue
  406.             continue
  407.  
  408.     except:
  409.         items = list('MakeSureHistoryArrayIsNotEmpty')
  410.  
  411.     return (tempHist, items, guids)
  412.  
  413.  
  414. def saveHistory(url, feedURL, encGUID, saveName, time, feedTitle, feedLink, saveDir, pubDate, itemTitle, fileID, status, description, location):
  415.     if DEBUG:
  416.         print 'Saving History...'
  417.     
  418.     histDict = {
  419.         'feedTitle': feedTitle,
  420.         'feedURL': feedURL,
  421.         'enclosureURL': url,
  422.         'encGUID': encGUID,
  423.         'file': saveName,
  424.         'downloadTime': time,
  425.         'path': saveDir,
  426.         'pubDate': pubDate,
  427.         'entryTitle': itemTitle,
  428.         'importedID': fileID,
  429.         'status': bool(status),
  430.         'description': description,
  431.         'import': location,
  432.         'status': status }
  433.     History['downloadHistory'].append(histDict)
  434.     History.write(historyFile)
  435.     historyURLs.append(url)
  436.     encGUIDs.append(encGUID)
  437.     anonFeedback = 1
  438.     
  439.     try:
  440.         anonFeedback = int(Prefs['anonFeedback'])
  441.     except:
  442.         pass
  443.  
  444.     if anonFeedback and status > 0:
  445.         pingURL = 'http://directory.iPodderX.com/feedData/survey/files?url=' + url + '&feed=' + feedURL
  446.         if DEBUG:
  447.             print 'Pinging survey server: ' + pingURL
  448.         
  449.         
  450.         try:
  451.             handle = urllib.urlopen(pingURL)
  452.  
  453.     
  454.     if DEBUG:
  455.         print 'Done saving History...'
  456.     
  457.  
  458.  
  459. def dummychoose(default, size, saveas, dir):
  460.     globals()['totalBTFileSize'] = float(size) / (1 << 20)
  461.     return saveas
  462.  
  463.  
  464. def dummydisplay(dict):
  465.     
  466.     try:
  467.         print ';;%.2f;;%.2f' % (totalBTFileSize, dict['downTotal'])
  468.         sys.stdout.flush()
  469.     except Exception:
  470.         inst = None
  471.  
  472.  
  473.  
  474. def dummyerror(message):
  475.     logIt(message)
  476.  
  477.  
  478. def getTorrent(torrent, maxUploadRate, saveLocation, saveName):
  479.     logIt('Downloading Torrent: ' + torrent)
  480.     print 'Downloading ' + saveName
  481.     sys.stdout.flush()
  482.     
  483.     try:
  484.         checkDir(saveLocation)
  485.         ev = Event()
  486.         
  487.         def fin(ev = ev):
  488.             ev.set()
  489.  
  490.         params = [
  491.             '--url',
  492.             torrent,
  493.             '--max_upload_rate',
  494.             maxUploadRate,
  495.             '--saveas',
  496.             saveLocation + '/' + saveName]
  497.         download.download(params, dummychoose, dummydisplay, fin, dummyerror, ev, 80)
  498.         logIt('Completed Download: %s' % saveName)
  499.     except Exception:
  500.         msg = None
  501.         logIt('Torrent Download Failed')
  502.         logIt('ERRORMSG: ' + str(msg))
  503.  
  504.  
  505.  
  506. def displayProgress(block_count, block_size, total_size):
  507.     print ';;%.2f;;%.2f' % (float(total_size) / 1024, float(block_count * block_size) / 1024)
  508.     sys.stdout.flush()
  509.  
  510.  
  511. def getFile(url, saveLocation, saveName):
  512.     status = 1
  513.     logIt('Downloading File: ' + url)
  514.     print 'Downloading ' + saveName
  515.     sys.stdout.flush()
  516.     checkDir(saveLocation)
  517.     
  518.     try:
  519.         headers = urllib.urlretrieve(url, saveLocation + '/' + saveName, displayProgress)
  520.         logIt('Completed Download: %s' % saveName)
  521.         status = 1
  522.     except Exception:
  523.         msg = None
  524.         logIt('Download Failed')
  525.         logIt(str(msg))
  526.         status = 0
  527.         return status
  528.  
  529.  
  530.  
  531. def getRSS(feed, etagInfo):
  532.     etagInfoNew = ''
  533.     
  534.     try:
  535.         if len(etagInfo) > 1:
  536.             parsedFeed = feedparser.parse(feed, etag = etagInfo, agent = USER_AGENT)
  537.             
  538.             try:
  539.                 etagInfoNew = parsedFeed.etag
  540.  
  541.         else:
  542.             parsedFeed = feedparser.parse(feed, agent = USER_AGENT)
  543.             
  544.             try:
  545.                 etagInfoNew = parsedFeed.etag
  546.             except:
  547.                 pass
  548.  
  549.         if parsedFeed.status == 304:
  550.             logIt('No new content found...')
  551.     except Exception:
  552.         inst = None
  553.         logIt('getRSS ERRMSG: ' + str(inst))
  554.         logIt('feedparser ERRMSG: ' + str(parsedFeed.debug_message))
  555.         logIt('Bozo Exceptoin: ' + parsedFeed['bozo_exception'])
  556.  
  557.     return (str(etagInfoNew), parsedFeed)
  558.  
  559.  
  560. def prepURL(url):
  561.     if url[:8] != 'https://':
  562.         if url[:7] != 'http://':
  563.             url = 'http://' + url
  564.         
  565.     
  566.     return url
  567.  
  568.  
  569. def url2file(url):
  570.     url = url.replace('http://', '')
  571.     url = url.replace('/', '.')
  572.     return url
  573.  
  574.  
  575. def feedIdHash(feedURL):
  576.     import md5
  577.     item = md5.new
  578.     item.create(feedURL)
  579.     return item.hexdigest
  580.  
  581.  
  582. def parseURL(url):
  583.     url = url.replace('http://', '')
  584.     split = url.split('/')
  585.     server = split[0]
  586.     rssFile = '/' + '/'.join(split[1:len(split)])
  587.     return (server, rssFile)
  588.  
  589.  
  590. def checkDir(dir):
  591.     if not os.path.isdir(dir):
  592.         os.mkdir(dir)
  593.     
  594.  
  595.  
  596. def checkForOtherInstances():
  597.     if int(os.popen('ps auxww | grep -i iPodderX.py | grep -v /bin/sh | grep -w -v ps | wc -l', 'r').readline().strip()) > 2:
  598.         logIt('iPodderX is already scanning your feeds with Auto Check')
  599.         print 'iPodderX is already scanning your feeds with Auto Check'
  600.         sys.exit()
  601.     
  602.  
  603.  
  604. def detectFileType(fileName):
  605.     logIt('Detecting file type...')
  606.     
  607.     try:
  608.         type = typeFile.file(fileName)
  609.     except Exception:
  610.         msg = None
  611.         logIt('Failed to detect type, using data')
  612.         logIt(msg)
  613.         type = data
  614.  
  615.     if re.search('ascii', type, re.IGNORECASE):
  616.         f = open(fileName, 'r')
  617.         for line in f.readlines():
  618.             if re.search('<html>', line, re.IGNORECASE):
  619.                 type = 'html'
  620.                 break
  621.                 continue
  622.         
  623.     
  624.     if re.search('xml', type, re.IGNORECASE):
  625.         f = open(fileName, 'r')
  626.         for line in f.readlines():
  627.             if re.search('<rss', line, re.IGNORECASE):
  628.                 type = 'rss'
  629.                 break
  630.                 continue
  631.             if re.search('<opml', line, re.IGNORECASE):
  632.                 type = 'opml'
  633.                 break
  634.                 continue
  635.         
  636.     
  637.     logIt('File type is ' + type)
  638.     return type
  639.  
  640.  
  641. def downloadFile(url, saveDir, saveName, folderName, customGenre):
  642.     fileID = 0
  643.     location = ''
  644.     status = 1
  645.     url = prepURL(url)
  646.     if re.search('torrent$', url, re.IGNORECASE):
  647.         saveName = saveName[0:len(saveName) - 8]
  648.         getTorrent(url, 0, saveDir, saveName)
  649.         type = detectFileType(saveDir + '/' + saveName)
  650.         if re.search('audio', type, re.IGNORECASE):
  651.             (fileID, location) = updatePlaylist(saveDir, saveName, folderName, customGenre)
  652.         elif re.search('image', type, re.IGNORECASE):
  653.             (fileID, location) = updateiPhoto(saveDir, saveName, folderName)
  654.         
  655.         return (saveName, fileID, location)
  656.     else:
  657.         status = getFile(url, saveDir, saveName)
  658.         if not (status == 0):
  659.             status = 1
  660.             type = detectFileType(saveDir + '/' + saveName)
  661.             if re.search('torrent', type, re.IGNORECASE):
  662.                 os.unlink(saveDir + saveName)
  663.                 if torrentFiles > 0:
  664.                     if re.search('.torrent$', type, re.IGNORECASE):
  665.                         saveName = saveName[0:len(saveName) - 8]
  666.                     
  667.                     getTorrent(url, 0, saveDir, saveName)
  668.                     type = typeFile.file(saveDir + '/' + saveName)
  669.                     if re.search('audio', type, re.IGNORECASE):
  670.                         (fileID, location) = updatePlaylist(saveDir, saveName, folderName, customGenre)
  671.                     elif re.search('image', type, re.IGNORECASE):
  672.                         (fileID, location) = updateiPhoto(saveDir, saveName, folderName)
  673.                     
  674.                 
  675.             elif re.search('audio', type, re.IGNORECASE):
  676.                 if moveAudio > 0:
  677.                     (fileID, location) = updatePlaylist(saveDir, saveName, folderName, customGenre)
  678.                 
  679.             elif re.search('image', type, re.IGNORECASE):
  680.                 if moveImages > 0:
  681.                     (fileID, location) = updateiPhoto(saveDir, saveName, folderName)
  682.                 
  683.             elif re.search('html', type, re.IGNORECASE):
  684.                 os.unlink(saveDir + saveName)
  685.                 return None
  686.             
  687.             return (saveName, fileID, location)
  688.         else:
  689.             os.unlink(saveDir + saveName)
  690.             return status
  691.  
  692. if __name__ == '__main__':
  693.     downloadCount = 0
  694.     for arg in sys.argv:
  695.         if arg == '-debug':
  696.             DEBUG = 1
  697.             continue
  698.     
  699.     if DEBUG:
  700.         print '--- DEBUG ENABLED ---'
  701.     
  702.     if checkReg() == 0:
  703.         print USER_AGENT + ' is UNREGISTERED, Please register today!'
  704.         sys.exit(0)
  705.     
  706.     checkForOtherInstances()
  707.     trimLog()
  708.     logIt('\r\n' + 'iPodderX (' + VERSION + ') Feed Scan Started: ' + strftime('%H:%M:%S -- %m/%d/%Y', localtime()))
  709.     downloadDirectory = downloadDir()
  710.     
  711.     try:
  712.         onlyAudio = int(Prefs['onlyAudio'])
  713.     except:
  714.         onlyAudio = 0
  715.  
  716.     
  717.     try:
  718.         moveAudio = int(Prefs['moveAudio'])
  719.     except:
  720.         moveAudio = 1
  721.  
  722.     
  723.     try:
  724.         moveImages = int(Prefs['moveImages'])
  725.     except:
  726.         moveImages = 1
  727.  
  728.     
  729.     try:
  730.         deleteAudio = int(Prefs['deleteAudio'])
  731.     except:
  732.         deleteAudio = 0
  733.  
  734.     
  735.     try:
  736.         deleteImages = int(Prefs['deleteImages'])
  737.     except:
  738.         deleteImages = 0
  739.  
  740.     
  741.     try:
  742.         torrentFiles = int(Prefs['torrentFiles'])
  743.     except:
  744.         torrentFiles = 1
  745.  
  746.     
  747.     try:
  748.         organizeDownloads = int(Prefs['organizeDownloads'])
  749.     except:
  750.         organizeDownloads = 0
  751.  
  752.     initialize()
  753.     (History, historyURLs, encGUIDs) = getHistory()
  754.     feedDetails = FeedListPrefs['iPodderXFeeds']
  755.     if len(historyURLs) == 0:
  756.         historyURLs = [
  757.             'MakeSureHistoryArrayIsNotEmpty']
  758.     
  759.     if len(encGUIDs) == 0:
  760.         encGUIDs = [
  761.             'MakeSureGUIDArrayIsNotEmpty']
  762.     
  763.     for feed in feedDetails:
  764.         counter = 10000000
  765.         podcasts = { }
  766.         
  767.         try:
  768.             enabled = feed['enabled']
  769.         except:
  770.             enabled = 1
  771.  
  772.         
  773.         try:
  774.             downloadBehavior = int(feed['downloadBehavior'])
  775.         except:
  776.             downloadBehavior = 0
  777.  
  778.         
  779.         try:
  780.             customFolder = feed['customFolder']
  781.         except:
  782.             customFolder = ''
  783.  
  784.         
  785.         try:
  786.             customGenre = feed['customGenre']
  787.         except:
  788.             customGenre = ''
  789.  
  790.         
  791.         try:
  792.             if enabled:
  793.                 print 'Checking ' + feed['feedTitle'] + '...'
  794.                 sys.stdout.flush()
  795.         except:
  796.             pass
  797.  
  798.         if enabled:
  799.             feedURL = prepURL(feed['feedURL'])
  800.             logIt('Checking ' + feedURL + '...')
  801.             parsedFeed = { }
  802.             
  803.             try:
  804.                 if DEBUG:
  805.                     (etag, parsedFeed) = getRSS(feedURL, '')
  806.                 else:
  807.                     
  808.                     try:
  809.                         (etag, parsedFeed) = getRSS(feedURL, feed['etag'])
  810.                     except:
  811.                         (etag, parsedFeed) = getRSS(feedURL, '')
  812.  
  813.             except Exception:
  814.                 inst = None
  815.                 logIt('Error parsing feed. RSS may be poorly formatted...')
  816.                 logIt('ERRMSG: ' + str(inst))
  817.  
  818.             
  819.             try:
  820.                 
  821.                 try:
  822.                     itemList = parsedFeed.entries
  823.                 except Exception:
  824.                     inst = None
  825.                     logIt('Error getting items')
  826.                     logIt('ERRMSG: ' + str(inst))
  827.  
  828.                 if len(itemList) > 0:
  829.                     
  830.                     try:
  831.                         feedTitle = latin1_to_ascii(parsedFeed.feed.title)
  832.                     except:
  833.                         pass
  834.  
  835.                     
  836.                     try:
  837.                         itemDescription = latin1_to_ascii(item['description'])
  838.                     except:
  839.                         itemDescription = 'No description'
  840.  
  841.                     
  842.                     try:
  843.                         feedLink = parsedFeed.feed.link
  844.                     except:
  845.                         feedLink = feedURL
  846.  
  847.                     feed['lastChecked'] = strftime('%a, %d %b %Y %H:%M:%S %Z', localtime())
  848.                     feed['etag'] = etag
  849.                     feed['feedTitle'] = feedTitle
  850.                     feed['siteURL'] = feedLink
  851.                     feed['downloadBehavior'] = '0'
  852.                 
  853.                 if len(itemList) > 0:
  854.                     for item in itemList:
  855.                         
  856.                         try:
  857.                             if item['modified_parsed'] == None:
  858.                                 pubDate = gmtime()
  859.                             else:
  860.                                 pubDate = item['modified_parsed']
  861.                         except:
  862.                             pubDate = gmtime()
  863.  
  864.                         
  865.                         try:
  866.                             itemTitle = latin1_to_ascii(item['title'])
  867.                         except:
  868.                             itemTitle = 'No title'
  869.  
  870.                         
  871.                         try:
  872.                             itemDescription = latin1_to_ascii(item['description'])
  873.                         except:
  874.                             itemDescription = 'No description'
  875.  
  876.                         if len(customFolder) > 0:
  877.                             sortDir = customFolder
  878.                         elif organizeDownloads == 1:
  879.                             sortDir = strftime('%Y-%m-%d', pubDate)
  880.                         else:
  881.                             sortDir = feedTitle.replace('/', '-')
  882.                             if sortDir[0] == '.':
  883.                                 sortDir = 'dot' + sortDir[1:]
  884.                             
  885.                         saveDir = downloadDirectory + sortDir
  886.                         
  887.                         try:
  888.                             keywordsRaw = feed['keywords']
  889.                             keywords = keywordsRaw.split(',')
  890.                         except:
  891.                             keywords = []
  892.  
  893.                         
  894.                         try:
  895.                             url = latin1_to_ascii(item.enclosures[0].url)
  896.                         except:
  897.                             url = ''
  898.  
  899.                         
  900.                         try:
  901.                             length = item.enclosures[0].length
  902.                         except:
  903.                             length = ''
  904.  
  905.                         
  906.                         try:
  907.                             type = item.enclosures[0].type
  908.                         except:
  909.                             type = ''
  910.  
  911.                         
  912.                         try:
  913.                             encGUID = item.guid
  914.                         except:
  915.                             encGUID = latin1_to_ascii(item.enclosures[0].url)
  916.  
  917.                         if len(keywords) > 0:
  918.                             for keyword in keywords:
  919.                                 keywordSplit = keyword.split(' ')
  920.                                 for word in keywordSplit:
  921.                                     if re.search(word, url, re.IGNORECASE) and re.search(word, itemTitle, re.IGNORECASE) or re.search(word, itemDescription, re.IGNORECASE):
  922.                                         didFind = 1
  923.                                         counter -= 1
  924.                                         continue
  925.                                     didFind = 0
  926.                                 
  927.                             
  928.                         else:
  929.                             didFind = 1
  930.                         okDownload = 0
  931.                         if didFind:
  932.                             if len(url) > 0 and didFind > 0:
  933.                                 if encGUID in encGUIDs:
  934.                                     okDownload = 0
  935.                                 elif url in historyURLs:
  936.                                     okDownload = 0
  937.                                 else:
  938.                                     okDownload = 1
  939.                             
  940.                         else:
  941.                             okDownload = 0
  942.                         if okDownload:
  943.                             saveNameSplit = url.split('/')
  944.                             saveName = saveNameSplit[len(saveNameSplit) - 1]
  945.                             saveName = latin1_to_ascii(saveName)
  946.                             if re.search('php$', saveName, re.IGNORECASE) or re.search('asp$', saveName, re.IGNORECASE):
  947.                                 if re.search('audio', type, re.IGNORECASE):
  948.                                     saveName = saveName[:-4] + '.mp3'
  949.                                 
  950.                                 if re.search('image', type, re.IGNORECASE):
  951.                                     saveName = saveName[:-4] + '.jpg'
  952.                                 
  953.                                 if re.search('movie', type, re.IGNORECASE):
  954.                                     saveName = saveName[:-4] + '.mpeg'
  955.                                 
  956.                             
  957.                             
  958.                             try:
  959.                                 modTime = mktime(item['modified_parsed'])
  960.                                 podcasts['saveName' + '-' + str(modTime)] = (url, feedURL, encGUID, saveName, strftime('%a, %d %b %Y %H:%M:%S %Z', gmtime()), feedTitle, feedLink, saveDir, strftime('%a, %d %b %Y %H:%M:%S %Z', pubDate), itemTitle, itemDescription)
  961.                             podcasts['saveName' + '-' + str(counter)] = (url, feedURL, encGUID, saveName, strftime('%a, %d %b %Y %H:%M:%S %Z', gmtime()), feedTitle, feedLink, saveDir, strftime('%a, %d %b %Y %H:%M:%S %Z', pubDate), itemTitle, itemDescription)
  962.  
  963.                             continue
  964.                     
  965.             except Exception:
  966.                 inst = None
  967.                 logIt('Exception Caught: ' + str(inst))
  968.             except:
  969.                 None<EXCEPTION MATCH>Exception
  970.             
  971.  
  972.         None<EXCEPTION MATCH>Exception
  973.         totalDownloads = 0
  974.         
  975.         try:
  976.             keys = podcasts.keys()
  977.             keys.sort()
  978.             
  979.             try:
  980.                 if keys[0] < keys[1]:
  981.                     keys.reverse()
  982.             except:
  983.                 pass
  984.  
  985.             for key in keys:
  986.                 url = podcasts[key][0]
  987.                 feedURL = podcasts[key][1]
  988.                 encGUID = podcasts[key][2]
  989.                 saveName = podcasts[key][3]
  990.                 gmTime = podcasts[key][4]
  991.                 feedTitle = podcasts[key][5]
  992.                 feedLink = podcasts[key][6]
  993.                 saveDir = podcasts[key][7]
  994.                 pubDate = podcasts[key][8]
  995.                 itemTitle = podcasts[key][9]
  996.                 itemDescription = podcasts[key][10]
  997.                 saveHist = 1
  998.                 if downloadBehavior == 2 and totalDownloads < 3:
  999.                     
  1000.                     try:
  1001.                         (saveName, fileID, location) = downloadFile(url, saveDir, saveName, sortDir, customGenre)
  1002.                         totalDownloads = totalDownloads + 1
  1003.                         downloadCount = downloadCount + 1
  1004.                     except Exception:
  1005.                         inst = None
  1006.                         logIt('ERRMSG: ' + str(inst))
  1007.                         totalDownloads = totalDownloads + 1
  1008.                         saveHist = 0
  1009.  
  1010.                     if saveHist:
  1011.                         saveHistory(url, feedURL, encGUID, saveName, gmTime, feedTitle, feedLink, saveDir, pubDate, itemTitle, fileID, 1, itemDescription, location)
  1012.                     
  1013.                 saveHist
  1014.                 if downloadBehavior == 2 and totalDownloads > 2:
  1015.                     saveHistory(url, feedURL, encGUID, saveName, gmTime, feedTitle, feedLink, saveDir, pubDate, itemTitle, 0, 0, '', '')
  1016.                     continue
  1017.                 if downloadBehavior == 1 and totalDownloads < 1:
  1018.                     
  1019.                     try:
  1020.                         (saveName, fileID, location) = downloadFile(url, saveDir, saveName, sortDir, customGenre)
  1021.                         totalDownloads = totalDownloads + 1
  1022.                         downloadCount = downloadCount + 1
  1023.                     except Exception:
  1024.                         inst = None
  1025.                         logIt('ERRMSG: ' + str(inst))
  1026.                         totalDownloads = totalDownloads + 1
  1027.                         saveHist = 0
  1028.  
  1029.                     if saveHist:
  1030.                         saveHistory(url, feedURL, encGUID, saveName, gmTime, feedTitle, feedLink, saveDir, pubDate, itemTitle, fileID, 1, itemDescription, location)
  1031.                     
  1032.                 saveHist
  1033.                 if downloadBehavior == 1 and totalDownloads > 0:
  1034.                     saveHistory(url, feedURL, encGUID, saveName, gmTime, feedTitle, feedLink, saveDir, pubDate, itemTitle, 0, 0, '', '')
  1035.                     continue
  1036.                 if downloadBehavior == 0:
  1037.                     
  1038.                     try:
  1039.                         (saveName, fileID, location) = downloadFile(url, saveDir, saveName, sortDir, customGenre)
  1040.                         totalDownloads = totalDownloads + 1
  1041.                         downloadCount = downloadCount + 1
  1042.                     except Exception:
  1043.                         inst = None
  1044.                         logIt('ERRMSG: ' + str(inst))
  1045.                         totalDownloads = totalDownloads + 1
  1046.                         saveHist = 0
  1047.  
  1048.                     if saveHist:
  1049.                         saveHistory(url, feedURL, encGUID, saveName, gmTime, feedTitle, feedLink, saveDir, pubDate, itemTitle, fileID, 1, itemDescription, location)
  1050.                     
  1051.                 saveHist
  1052.         continue
  1053.         except Exception:
  1054.             inst = None
  1055.             logIt('ERRMSG: ' + str(inst))
  1056.             continue
  1057.         
  1058.  
  1059.     
  1060.     FeedListPrefs = plistlib.Plist.fromFile(file(feedFile))
  1061.     feedDetailsNew = FeedListPrefs['iPodderXFeeds']
  1062.     for feedNew in feedDetailsNew:
  1063.         for feedOld in feedDetails:
  1064.             
  1065.             try:
  1066.                 if feedNew['feedURL'] == feedOld['feedURL'] and feedOld['enabled'] > 0:
  1067.                     feedNew['etag'] = 'Temp Value'
  1068.                     feedNew.update(feedOld)
  1069.                     if DEBUG:
  1070.                         print 'Preferences for % has been updated' % feedNew['feedTitle']
  1071.                     
  1072.             continue
  1073.             continue
  1074.  
  1075.         
  1076.     
  1077.     FeedListPrefs['iPodderXFeeds'] = feedDetailsNew
  1078.     FeedListPrefs.write(feedFile)
  1079.     if downloadCount > 0:
  1080.         print 'Successfully downloaded %d podcasts' % downloadCount
  1081.         logIt('Successfully downloaded ' + str(downloadCount) + ' podcasts')
  1082.     
  1083.     logIt('iPodderX Feed Scan Complete: ' + strftime('%H:%M:%S -- %m/%d/%Y', localtime()))
  1084.  
  1085.